Crate const_format
source ·Expand description
Compile-time string formatting.
This crate provides types and macros for formatting strings at compile-time.
§Rust versions
There are some features that require a variety of stable Rust versions and others that require Rust nightly, the sections below describe the features that are available for each version.
§Rust 1.57.0
These macros are available in Rust 1.57.0:
-
concatcp
: Concatenatesintegers
,bool
,char
, and&str
constants into a&'static str
constant. -
formatcp
:format
-like formatting which takesintegers
,bool
,char
, and&str
constants, and emits a&'static str
constant. -
str_get
: Indexes a&'static str
constant, returningNone
when the index is out of bounds. -
str_index
: Indexes a&'static str
constant. -
str_repeat
: Creates a&'static str
by repeating a&'static str
constanttimes
times. -
str_splice
: Replaces a substring in a&'static str
constant. -
map_ascii_case
: Converts a&'static str
constant to a different casing style, determined by aCase
argument. -
str_replace
: Replaces all the instances of a pattern in a&'static str
constant with another&'static str
constant.
The "assertcp"
feature enables the assertcp
, assertcp_eq
,
and assertcp_ne
macros.
These macros are like the standard library assert macros,
but evaluated at compile-time,
with the limitation that they can only have primitive types as arguments
(just like concatcp
and formatcp
).
§Rust 1.64.0
The "rust_1_64"
feature enables these macros:
str_split
: splits a string constant
§Rust nightly
By enabling the “fmt” feature, you can use a std::fmt
-like API.
This requires the nightly compiler, because it uses mutable references in const fn, which have not been stabilized as of writing these docs.
All the other features of this crate are implemented on top of the const_format::fmt
API:
-
concatc
: Concatenates many standard library and user defined types into a&'static str
constant. -
formatc
:format
-like macro that can format many standard library and user defined types into a&'static str
constant. -
writec
:write
-like macro that can format many standard library and user defined types into a type that implementsWriteMarker
.
The "derive"
feature enables the ConstDebug
macro,
and the "fmt"
feature.
ConstDebug
derives the FormatMarker
trait,
and implements an inherent const_debug_fmt
method for compile-time debug formatting.
The "assertc"
feature enables the assertc
, assertc_eq
, assertc_ne
macros,
and the "fmt"
feature.
These macros are like the standard library assert macros, but evaluated at compile-time.
§Examples
§Concatenation of primitive types
use const_format::concatcp;
const NAME: &str = "Bob";
const FOO: &str = concatcp!(NAME, ", age ", 21u8,"!");
assert_eq!(FOO, "Bob, age 21!");
§Formatting primitive types
use const_format::formatcp;
const NAME: &str = "John";
const FOO: &str = formatcp!("{NAME}, age {}!", compute_age(NAME));
assert_eq!(FOO, "John, age 24!");
§Formatting custom types
This example demonstrates how you can use the ConstDebug
derive macro,
and then format the type into a &'static str
constant.
This example requires Rust nightly, and the "derive"
feature.
#![feature(const_mut_refs)]
use const_format::{ConstDebug, formatc};
#[derive(ConstDebug)]
struct Message{
ip: [Octet; 4],
value: &'static str,
}
#[derive(ConstDebug)]
struct Octet(u8);
const MSG: Message = Message{
ip: [Octet(127), Octet(0), Octet(0), Octet(1)],
value: "Hello, World!",
};
const FOO: &str = formatc!("{:?}", MSG);
assert_eq!(
FOO,
"Message { ip: [Octet(127), Octet(0), Octet(0), Octet(1)], value: \"Hello, World!\" }"
);
§Formatted const assertions
This example demonstrates how you can use the assertcp_ne
macro to
do compile-time inequality assertions with formatted error messages.
This requires the "assertcp"
feature.
use const_format::assertcp_ne;
macro_rules! check_valid_pizza{
($user:expr, $topping:expr) => {
assertcp_ne!(
$topping,
"pineapple",
"You can't put pineapple on pizza, {}",
$user,
);
}
}
check_valid_pizza!("John", "salami");
check_valid_pizza!("Dave", "sausage");
check_valid_pizza!("Bob", "pineapple");
This is the compiler output:
error[E0080]: evaluation of constant value failed
--> src/lib.rs:178:27
|
20 | check_valid_pizza!("Bob", "pineapple");
| ^^^^^^^^^^^ the evaluated program panicked at '
assertion failed: `(left != right)`
left: `"pineapple"`
right: `"pineapple"`
You can't put pineapple on pizza, Bob
', src/lib.rs:20:27
§Limitations
All of the macros from const_format
have these limitations:
-
The formatting macros that expand to
&'static str
s can only use constants from concrete types, so while aType::<u8>::FOO
argument would be fine,Type::<T>::FOO
would not be (T
being a type parameter). -
Integer arguments must have a type inferrable from context, more details in the Integer arguments section.
-
They cannot be used places that take string literals. So
#[doc = "foobar"]
cannot be replaced with#[doc = concatcp!("foo", "bar") ]
.
§Integer arguments
Integer arguments must have a type inferrable from context. so if you only pass an integer literal it must have a suffix.
Example of what does compile:
const N: u32 = 1;
assert_eq!(const_format::concatcp!(N + 1, 2 + N), "23");
assert_eq!(const_format::concatcp!(2u32, 2 + 1u8, 3u8 + 1), "234");
Example of what does not compile:
assert_eq!(const_format::concatcp!(1 + 1, 2 + 1), "23");
§Renaming crate
All function-like macros from const_format
can be used when the crate is renamed.
The ConstDebug
derive macro has the #[cdeb(crate = "foo::bar")]
attribute to
tell it where to find the const_format
crate.
Example of renaming the const_format
crate in the Cargo.toml file:
[dependencies]
cfmt = {version = "0.*", package = "const_format"}
§Cargo features
-
"fmt"
: Enables thestd::fmt
-like API, requires Rust nightly because it uses mutable references in const fn.
This feature includes theformatc
/writec
formatting macros. -
"derive"
: requires Rust nightly, implies the"fmt"
feature, provides theConstDebug
derive macro to format user-defined types at compile-time.
This implicitly uses thesyn
crate, so clean compiles take a bit longer than without the feature. -
"assertc"
: requires Rust nightly, implies the"fmt"
feature, enables theassertc
,assertc_eq
, andassertc_ne
assertion macros.
This feature was previously named"assert"
, but it was renamed to avoid confusion with the"assertcp"
feature. -
"assertcp"
: Enables theassertcp
,assertcp_eq
, andassertcp_ne
assertion macros. -
"rust_1_64"
: Enables thestr_split
macro. Allows theas_bytes_alt
methods andslice_up_to_len_alt
methods to run in constant time, rather than linear time (proportional to the truncated part of the slice).
§No-std support
const_format
is unconditionally #![no_std]
, it can be used anywhere Rust can be used.
§Minimum Supported Rust Version
const_format
requires Rust 1.57.0.
Features that require newer versions of Rust, or the nightly compiler, need to be explicitly enabled with cargo features.
Re-exports§
pub use crate::fmt::Error;
pub use crate::fmt::Formatter;
pub use crate::fmt::FormattingFlags;
pub use crate::fmt::Result;
pub use crate::fmt::StrWriter;
pub use crate::fmt::StrWriterMut;
Modules§
- fmt
fmt
std::fmt
-like api that can be used at compile-time. - for_
examples fmt
Types for the documentation examples. - Marker traits for types that can be formatted and/or be written to.
- utils
fmt
Miscelaneous functions. - Some wrapper types.
Macros§
- ascii_
str fmt
Constructs anAsciiStr
constant from an ascii string, - assertc
assertc
Compile-time assertions with formatting. - assertc_
eq assertc
Compile-time equality assertion with formatting. - assertc_
ne assertc
Compile-time inequality assertion with formatting. - assertcp
assertcp
Compile-time assertion with formatting. - assertcp_
eq assertcp
Compile-time equality assertion with formatting. - assertcp_
ne assertcp
Compile-time inequality assertion with formatting. - For debug formatting of some specific generic std types, and other types.
- Coerces a reference to a type that has a
const_*_fmt
method. - concatc
fmt
Concatenates constants of standard library and/or user-defined types into a&'static str
. - Concatenates constants of primitive types into a
&'static str
. - formatc
fmt
Formats constants of standard library and/or user-defined types into a&'static str
. - Formats constants of primitive types into a
&'static str
- impl_
fmt fmt
For implementing debug or display formatting “manually”. - Converts the casing style of a
&'static str
constant, ignoring non-ascii unicode characters. - Indexes a
&'static str
constant, returningNone
when the index is not on a character boundary. - Indexes a
&'static str
constant. - Creates a
&'static str
by repeating a&'static str
constanttimes
times - Replaces all the instances of
$pattern
in$input
(a&'static str
constant) with$replace_with
(a&'static str
constant). - Replaces a substring in a
&'static str
constant. Returns both the new resulting&'static str
, and the replaced substring. - str_
split rust_1_64
Splits$string
(a&'static str
constant) with$splitter
, returning an array of&'static str
s. - strwriter_
as_ str Deprecated fmt
Converts a&'static StrWriter
to a&'static str
, in aconst
/static
initializer. - try_
fmt
For returning early on an error, otherwise evaluating to()
. - unwrap
fmt
Equivalent toResult::unwrap
, for use withconst_format::Error
errors. - Equivalent to
Result::unwrap_or_else
but allows returning from the enclosing function. - writec
fmt
Writes some formatted standard library and/or user-defined types into a buffer.
Structs§
- Ascii
Str fmt
An ascii string slice. - PWrapper
fmt
Wrapper for many std types, which implements theconst_debug_fmt
and/orconst_display_fmt
methods for them. - Sliced
fmt
Wrapper for writing a range of a string slice. - The return value of
str_splice
Enums§
- The casing style of a string.
Derive Macros§
- Const
Debug derive
Derives const debug formatting for a type.